// 皇冠协议读取比赛数据
const axios = require('axios');
const { parseStringPromise } = require('xml2js');
const dataHandler = require("../data_handler");

const GAME_MAP = new Map();

class HgaGameListFetcher {
    /**
     * @param {Object} options
     * @param {string} options.cookie - 当前账号cookie
     * @param {string} options.ver - 当前账号版本
     * @param {string} options.param - 当前账号param参数（除最后ts）
     * @param {string} options.host - 域名，如 'hga030.com'
     * @param {function} options.onData - 获取合并后数据时回调 (data) => {}
     * @param {WebSocket} [options.ws] - 可选，用于判断ws状态
     */
    constructor({ cookie, ver, param, host }, username) {
        this.cookie = cookie;
        this.ver = ver;
        this.param = param;
        this.host = host;
        this.running = false;
        this.username = username;
    }


    async start(lang) {
        await this.loop(lang);
    }

    stop() {
        this.running = false;
    }

    async loop(lang) {
        try {
            const data = await this.fetchGameList(lang);
            const obj = await this.xml2json(data);
            const result = this.getData(obj);
            if (result.length > 0) {
                GAME_MAP.set(lang, {
                    list: result,
                    time: Date.now()
                });
                const merged = this.gameListHandler();
                if (merged) {
                    dataHandler.update_hga_data(merged);
                }
            }
        } catch (err) {
            console.error(`[${lang}] 拉取失败:`, err.message);
        }
    }

    async fetchGameList(lang) {
        let v = this.param;
        if (lang === 'en-us') {
            v = v.replace("&langx=zh-cn", "&langx=en-us");
        } else {
            v = v.replace("&langx=en-us", "&langx=zh-cn");
        }
        const body = v +
            "&p=get_game_list&p3type=&date=&gtype=ft&showtype=live&rtype=rrnou&ltype=3&cupFantasy=N&sorttype=L&specialClick=&isFantasy=N&ts=" +
            Date.now();

        const url = `https://${this.host}/transform.php?ver=${this.ver}`;

        const headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
            "Accept": "*/*",
            "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
            "Content-Type": "application/x-www-form-urlencoded",
            "Sec-Fetch-Dest": "empty",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Site": "same-origin",
            "Cookie": this.cookie,
            "Referer": `https://${this.host}/`
        };
        const res = await axios.post(url, body, { headers });
        return res.data;
    }

    async xml2json(xml) {
        const result = await parseStringPromise(xml, { explicitArray: false });
        return result;
    }

    getData(data) {
        let dataResult = []
        let list = data.serverresponse.ec;
        if (!list) {
            console.info("没有获取到滚球数据:", data);
            if (data.serverresponse.msg == "doubleLogin") {
                global.info("删除用户信息，等待重新登录");
                global.AccountMap.has(this.username) && global.AccountMap.delete(this.username);
                return false;
            }
            return dataResult;
        }
        if (!list.length) list = [list]
        // console.info("HG比赛数量:", list.length);
        for (let i = 0; i < list.length; i++) {
            let item = list[i]
            let game = item.game
            let id = item.game.GID;
            if (id) {
                let league = game.LEAGUE;
                if (league.indexOf("EFootball - ") == 0 || league.indexOf("电竞足球") == 0) {
                    continue;
                }
                let home = game.TEAM_H
                let away = game.TEAM_C
                let homeScore = game.SCORE_H;
                let awayScore = game.SCORE_C;
                let homeRed = game.REDCARD_H
                let awayRed = game.REDCARD_C
                let period = game.RETIMESET
                let systemTime = game.SYSTIME
                let datetime = game.DATETIME
                let markets = []
                // 强队标识 重要：处理数据过程：将hdp作为主队的让球数，也就是在使用hdp的时候，hdp的值代表的是主队的让球/受让
                let strong = game.STRONG

                // 全场让球  盘口1
                let handicap = game.RATIO_RE
                if (handicap) {
                    let market = this.getMarket("RE", "all_hdp_", "滚球让球", handicap, game.IOR_REH, game.IOR_REC, strong, game.GID)
                    markets.push(market);
                }
                // 全场让球  盘口2
                handicap = game.A_sub_RATIO_RE
                strong = game.A_sub_STRONG
                if (handicap) {
                    let market = this.getMarket("RE", "all_hdp_", "滚球让球", handicap, game.A_sub_IOR_REH, game.A_sub_IOR_REC, strong, game.A_sub_GID)
                    markets.push(market);
                }
                // 全场让球  盘口3
                handicap = game.B_sub_RATIO_RE
                strong = game.B_sub_STRONG
                if (handicap) {
                    let market = this.getMarket("RE", "all_hdp_", "滚球让球", handicap, game.B_sub_IOR_REH, game.B_sub_IOR_REC, strong, game.B_sub_GID)
                    markets.push(market);
                }

                // 半场让球  盘口1
                handicap = game.RATIO_HRE
                strong = game.HSTRONG
                if (handicap) {
                    let market = this.getMarket("HRE", "1h_hdp_", "滚球上半场让球", handicap, game.IOR_HREH, game.IOR_HREC, strong, game.HGID)
                    markets.push(market);
                }
                // 半场让球  盘口2
                handicap = game.A_sub_RATIO_HRE
                strong = game.A_sub_HSTRONG
                if (handicap) {
                    let market = this.getMarket("HRE", "1h_hdp_", "滚球上半场让球", handicap, game.A_sub_IOR_HREH, game.A_sub_IOR_HREC, strong, game.A_sub_HGID)
                    markets.push(market);
                }
                // 半场让球  盘口3
                handicap = game.B_sub_RATIO_HRE
                strong = game.B_sub_HSTRONG
                if (handicap) {
                    let market = this.getMarket("HRE", "1h_hdp_", "滚球上半场让球", handicap, game.B_sub_IOR_HREH, game.B_sub_IOR_HREC, strong, game.B_sub_HGID)
                    markets.push(market);
                }
                //RATIO_ROUO 全场大小 盘口1
                handicap = game.RATIO_ROUO
                if (handicap) {
                    let market = this.getMarket("ROU", "all_ou_", "滚球大小", handicap, game.IOR_ROUC, game.IOR_ROUH, false, game.GID)
                    markets.push(market);
                }
                //RATIO_ROUO 全场大小 盘口2
                handicap = game.A_sub_RATIO_ROUO
                if (handicap) {
                    let market = this.getMarket("ROU", "all_ou_", "滚球大小", handicap, game.A_sub_IOR_ROUC, game.A_sub_IOR_ROUH, false, game.A_sub_GID)
                    markets.push(market);
                }
                //RATIO_ROUO 全场大小 盘口3
                handicap = game.B_sub_RATIO_ROUO
                if (handicap) {
                    let market = this.getMarket("ROU", "all_ou_", "滚球大小", handicap, game.B_sub_IOR_ROUC, game.B_sub_IOR_ROUH, false, game.B_sub_GID)
                    markets.push(market);
                }


                handicap = game.RATIO_HROUO
                if (handicap) {
                    let market = this.getMarket("HROU", "1h_ou_", "滚球上半场大小", handicap, game.IOR_HROUC, game.IOR_HROUH, false, game.GID)
                    markets.push(market);
                }
                //RATIO_ROUO 全场大小 盘口2
                handicap = game.A_sub_RATIO_HROUO
                if (handicap) {
                    let market = this.getMarket("HROU", "1h_ou_", "滚球上半场大小", handicap, game.A_sub_IOR_HROUC, game.A_sub_IOR_HROUH, false, game.A_sub_HGID)
                    markets.push(market);
                }
                //RATIO_ROUO 全场大小 盘口3


                handicap = game.B_sub_RATIO_ROUO
                if (handicap) {
                    let market = this.getMarket("HROU", "1h_ou_", "滚球上半场大小", handicap, game.B_sub_IOR_HROUC, game.B_sub_IOR_HROUH, false, game.B_sub_HGID)
                    markets.push(market);
                }
                let match = {
                    id, league, home, away, homeScore, awayScore, homeRed, awayRed, period,
                }
                let result = {
                    match, markets
                }
                dataResult.push(result)
            }
        }
        return dataResult;
    }

    getMarket(wtype, id, type, handicap, home, away, strong, gid) {
        let hdp = handicap.split(" / ")
        if (hdp.length == 2) {
            hdp = (parseFloat(hdp[0]) + parseFloat(hdp[1])) / 2
        } else {
            hdp = hdp[0]
        }
        if (hdp != "0" && strong) {
            if (strong == "H") {
                hdp = "-" + hdp;
            }
        }
        let odds = this.convertHKOdds(home, away)
        return {
            id: gid,// 盘口
            type: type,
            wtype: wtype,
            handicap: hdp,
            homeOdds: home ? parseFloat(odds[0]).toFixed(2) : "",
            awayOdds: away ? parseFloat(odds[1]).toFixed(2) : ""
        }
    }

    gameListHandler() {
        const zhList = GAME_MAP.get('zh-cn');
        const enList = GAME_MAP.get('en-us');
        if (!zhList || !enList) return false;

        const isZhNew = zhList.time >= enList.time;
        const enMap = new Map(enList.list.map(item => [item.match.id, item]));

        const mergedList = [];
        for (const zhItem of zhList.list) {
            const enItem = enMap.get(zhItem.match.id);
            if (!enItem) continue;
            mergedList.push({
                match: {
                    id: zhItem.match.id,
                    zh: {
                        league: zhItem.match.league,
                        home: zhItem.match.home,
                        away: zhItem.match.away
                    },
                    en: {
                        league: enItem.match.league,
                        home: enItem.match.home,
                        away: enItem.match.away
                    },
                    homeScore: isZhNew ? zhItem.match.homeScore : enItem.match.homeScore,
                    awayScore: isZhNew ? zhItem.match.awayScore : enItem.match.awayScore,
                    homeRed: isZhNew ? zhItem.match.homeRed : enItem.match.homeRed,
                    awayRed: isZhNew ? zhItem.match.awayRed : enItem.match.awayRed,
                    period: isZhNew ? zhItem.match.period : enItem.match.period
                },
                markets: isZhNew ? zhItem.markets : enItem.markets
            });
        }
        return mergedList.length > 0 ? mergedList : false;
    }


    convertHKOdds(iorH, iorC) {
        // 转成乘 1000 的整数
        let H_ratio = Math.floor(parseFloat(iorH) * 1000 + 0.001);
        let C_ratio = Math.floor(parseFloat(iorC) * 1000 + 0.001);

        // 如果都 <= 1000，直接返回保留两位小数
        if (H_ratio <= 1000 && C_ratio <= 1000) {
            return [
                (H_ratio / 1000).toFixed(2),
                (C_ratio / 1000).toFixed(2)
            ];
        }

        // 以下是原 get_HK_ior 精简逻辑
        let line = 2000 - (H_ratio + C_ratio);
        let lowRatio, highRatio, nowRatio;
        let nowType = "";

        if (H_ratio > C_ratio) {
            lowRatio = C_ratio;
            nowType = "C";
        } else {
            lowRatio = H_ratio;
            nowType = "H";
        }

        if (2000 - line - lowRatio > 1000) {
            nowRatio = (lowRatio + line) * -1;
        } else {
            nowRatio = 2000 - line - lowRatio;
        }

        if (nowRatio < 0) {
            highRatio = Math.floor(Math.abs(1000 / nowRatio) * 1000);
        } else {
            highRatio = 2000 - line - nowRatio;
        }

        let outH, outC;
        if (nowType === "H") {
            outH = Math.floor(lowRatio / 10 + 0.0001) * 10;
            outC = Math.floor(highRatio / 10 + 0.0001) * 10;
        } else {
            outH = Math.floor(highRatio / 10 + 0.0001) * 10;
            outC = Math.floor(lowRatio / 10 + 0.0001) * 10;
        }

        return [
            (outH / 1000).toFixed(2),
            (outC / 1000).toFixed(2)
        ];
    }
}

module.exports = HgaGameListFetcher;
